
#include <BLabel>
#include <BGridLayout>
#include <BVBoxLayout>
#include <BHBoxLayout>
#include <BMenu>
#include <BApplication>

#include "WidgetPanel.h"

WidgetPanel::WidgetPanel(BWidget* parent) : BGroupBox(parent)
{
	this->setTitle("Widget");

	_widget = 0;

	BMenu* widthPolicyMenu = new BMenu();
	{
		widthPolicyMenu->addAction("None")->setAsset(Policy_None);
		widthPolicyMenu->addAction("Fixed")->setAsset(Policy_Fixed);
		widthPolicyMenu->addAction("Preferred")->setAsset(Policy_Preferred);
		widthPolicyMenu->addAction("Shrinking")->setAsset(Policy_Shrinking);
		widthPolicyMenu->addAction("Expanding")->setAsset(Policy_Expanding);
		for (int i = 0; i < widthPolicyMenu->count(); i++)
			widthPolicyMenu->action(i)->setCheckable(true);
	}

	BMenu* heightPolicyMenu = new BMenu();
	{
		heightPolicyMenu->addAction("None")->setAsset(Policy_None);
		heightPolicyMenu->addAction("Fixed")->setAsset(Policy_Fixed);
		heightPolicyMenu->addAction("Preferred")->setAsset(Policy_Preferred);
		heightPolicyMenu->addAction("Shrinking")->setAsset(Policy_Shrinking);
		heightPolicyMenu->addAction("Expanding")->setAsset(Policy_Expanding);
		for (int i = 0; i < heightPolicyMenu->count(); i++)
			heightPolicyMenu->action(i)->setCheckable(true);
	}

	BGridLayout* gridLayout = new BGridLayout();
	{
		BLabel* titleLabel = new BLabel("title");
		_titleEdit = new BLineEdit();

		BLabel* framelessLabel = new BLabel("frameless");
		_framelessCheckBox = new BCheckBox();

		BLabel* posLabel = new BLabel("pos");
		BHBoxLayout* posLayout = new BHBoxLayout();
		{
			_posXSpinBox = new BSpinBox(0, 9999);
			_posYSpinBox = new BSpinBox(0, 9999);
			posLayout->addWidget(_posXSpinBox);
			posLayout->addWidget(_posYSpinBox);
		}

		BLabel* sizeLabel = new BLabel("size");
		BHBoxLayout* sizeLayout = new BHBoxLayout();
		{
			_widthSpinBox = new BSpinBox(0, 9999);
			_heightSpinBox = new BSpinBox(0, 9999);
			sizeLayout->addWidget(_widthSpinBox);
			sizeLayout->addWidget(_heightSpinBox);
		}

		BLabel* styleSheetLabel = new BLabel("style-sheet");
		_styleSheetButton = new BButton();
		_styleSheetButton->setCheckable(true);

		gridLayout->addWidget(0, 0, titleLabel);
		gridLayout->addWidget(0, 1, _titleEdit);
		gridLayout->addWidget(1, 0, framelessLabel);
		gridLayout->addWidget(1, 1, _framelessCheckBox);
		gridLayout->addWidget(2, 0, posLabel);
		gridLayout->addLayout(2, 1, posLayout);
		gridLayout->addWidget(3, 0, sizeLabel);
		gridLayout->addLayout(3, 1, sizeLayout);
		gridLayout->addWidget(4, 0, styleSheetLabel);
		gridLayout->addWidget(4, 1, _styleSheetButton);
		gridLayout->setColumnStretch(1, 100);
	}

	BVBoxLayout* vlayout = new BVBoxLayout(this);
	vlayout->addLayout(gridLayout);

	_styleSheetDialog = new StyleSheetDialog();
	_styleSheetDialog->setSize(400, 400);

	connect(this, Signal_AssetChanged, &WidgetPanel::slotAssetChanged);
	connect(_posXSpinBox, Signal_EditFinished, &WidgetPanel::slotPosEditFinished);
	connect(_posYSpinBox, Signal_EditFinished, &WidgetPanel::slotPosEditFinished);
	connect(_widthSpinBox, Signal_EditFinished, &WidgetPanel::slotSizeEditFinished);
	connect(_heightSpinBox, Signal_EditFinished, &WidgetPanel::slotSizeEditFinished);
	connect(_styleSheetButton, Signal_Toggled, &WidgetPanel::slotStyleSheetButtonToggled);
	connect(_styleSheetDialog, Signal_Finished, &WidgetPanel::slotStyleSheetDialogFinished);
	connect(_styleSheetDialog, Signal_Hide, &WidgetPanel::slotStyleSheetDialogHide);
}
WidgetPanel::~WidgetPanel()
{

}

Policy WidgetPanel::policyFromMenu(BMenu* menu, BString& text)
{
	text.reset();
	Policy policy = 0;
	for (int i = 0; i < menu->count(); i++)
	{
		BAction* action = menu->action(i);
		if (action->checked())
		{
			text << action->text() << '|';
			PolicyFlag p = action->asset();
			policy |= p;
		}
	}
	text -= '|';
	return policy;
}

void WidgetPanel::slotAssetChanged()
{
	BWidget* widget = this->asset();
	if (_widget != widget)
	{
		if (_widget)
		{
			disconnect(_widget);
		}
		_widget = widget;
		if (_widget)
		{
			_titleEdit->setText(_widget->title());
			_framelessCheckBox->setChecked(_widget->frameless());
			_posXSpinBox->setValue(_widget->pos().x());
			_posYSpinBox->setValue(_widget->pos().y());
			_widthSpinBox->setValue(_widget->width());
			_heightSpinBox->setValue(_widget->height());
			_styleSheetButton->setText(_widget->styleSheet());
			connect(_widget, Signal_Moved, &WidgetPanel::slotWidgetMoved);
			connect(_widget, Signal_Resized, &WidgetPanel::slotWidgetResized);
			connect(_widget, Signal_TitleChanged, &WidgetPanel::slotWidgetTitleChanged);
		}
		this->setEnabled(_widget);
	}
}

void WidgetPanel::slotWidgetMoved(BObject* object, const BValue& value)
{
	BPoint pos = value;
	_posXSpinBox->setValue(pos.x());
	_posYSpinBox->setValue(pos.y());
}
void WidgetPanel::slotWidgetResized(BObject* object, const BValue& value)
{
	BSize size = value;
	_widthSpinBox->setValue(size.width());
	_heightSpinBox->setValue(size.height());
}
void WidgetPanel::slotWidgetTitleChanged(BObject* object, const BValue& value)
{
	const BString& title = value;
	_titleEdit->setText(title);
}

void WidgetPanel::slotPosEditFinished()
{
	int x = _posXSpinBox->value();
	int y = _posYSpinBox->value();
	_widget->setPos(x, y);
}
void WidgetPanel::slotSizeEditFinished()
{
	int width = _widthSpinBox->value();
	int height = _heightSpinBox->value();
	_widget->setSize(width, height);
}

void WidgetPanel::slotStyleSheetButtonToggled(BObject* object, const BValue& value)
{
	if (value)
	{
		_styleSheetDialog->setParent(BApplication::activeWindow());
		_styleSheetDialog->setSheet(_widget->styleSheet());
		_styleSheetDialog->show();
	}
	else
	{
		_styleSheetDialog->setSheet(BString());
		_styleSheetDialog->hide();
	}
}
void WidgetPanel::slotStyleSheetDialogFinished(BObject* object, const BValue& value)
{
	const BString& sheet = _styleSheetDialog->sheet();
	_widget->setStyleSheet(sheet);
	BString briefSheet = sheet.line(0);
	briefSheet << " ...";
	_styleSheetButton->setText(sheet);
}
void WidgetPanel::slotStyleSheetDialogHide(BObject* object, const BValue& value)
{
	_styleSheetButton->setChecked(false);
}
